home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl2 / demos / pixmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  6.2 KB  |  272 lines

  1. /* pixmap.c
  2.  * This program renders a scene to either a pixmap or a window.
  3.  * The scene from the pixmap can be copied forward the to window.
  4.  * The scenes are slightly different so that is clear when the
  5.  * pixmap is being copied, and when the program is rendering directly
  6.  * to the window. 
  7.  *
  8.  * Original Author: Lesley Kalmin, SGI
  9.  * 
  10.  * Hit p to render to a pixmap, w to render to a window, and c to copy
  11.  * forward from the pixmap to the window.
  12.  */
  13.  
  14. /*
  15. ** $Revision: 1.2 $
  16. ** $Date: 1996/07/09 23:19:13 $
  17. */
  18. #include <GL/glx.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <X11/keysym.h>
  22.  
  23. static int RGBattributes[] = {
  24.     GLX_RGBA,
  25.     GLX_RED_SIZE, 1,
  26.     GLX_GREEN_SIZE, 1,
  27.     GLX_BLUE_SIZE, 1,
  28.     None,
  29. };
  30.  
  31. static int CIattributes[] = {
  32.     GLX_DEPTH_SIZE, 1,
  33.     None,
  34. };
  35.  
  36. int width = 200, height = 200;
  37.  
  38. /* render an extra triangle to the pixmap
  39.  * so that we can tell the difference between
  40.  * the scene rendered to the window and the
  41.  * one copied from the pixmap 
  42.  */
  43. GLboolean render_to_pixmap = GL_TRUE;
  44.  
  45. static void Reshape(int w, int h)
  46. {
  47.     glViewport(0, 0, (GLint)w, (GLint)h);
  48.  
  49.     width = w;
  50.     height = h;
  51.  
  52.     glMatrixMode(GL_PROJECTION);
  53.     glLoadIdentity();
  54.     glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);
  55.     glMatrixMode(GL_MODELVIEW);
  56. }
  57.  
  58.  
  59. static void Init(void)
  60. {
  61.  
  62.     glClearColor(0.0, 0.0, 0.0, 0.0);
  63.     glClearIndex(1.0);
  64.  
  65.     glClearDepth(1);
  66.     glClearStencil(0);
  67.     glEnable(GL_DEPTH_TEST);
  68. }
  69.  
  70.  
  71.  
  72. static void DoDisplay(void)
  73. {
  74.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  75.  
  76.     glColor3ub(200, 0, 0);
  77.     glIndexi(2);
  78.     glBegin(GL_TRIANGLES);
  79.     glVertex3i(-4, -3, -2);
  80.     glVertex3i( 4, -3, -2);
  81.     glVertex3i( 0,  4, -2);
  82.     glEnd();
  83.  
  84.     glEnable(GL_SCISSOR_TEST);
  85.     glScissor(width/3, height/3, width/3, height/3);
  86.     glColor3ub(0, 200, 0);
  87.     glIndexi(29);
  88.     glBegin(GL_TRIANGLES);
  89.     glVertex3i(-4, -3, 0);
  90.     glVertex3i( 4, -3, 0);
  91.     glVertex3i( 0,  4, 0);
  92.     glEnd();
  93.     glDisable(GL_SCISSOR_TEST);
  94.  
  95.     if (render_to_pixmap) {
  96.     glColor3ub(0, 0, 200);
  97.     glIndexi(31);
  98.     glBegin(GL_TRIANGLES);
  99.         glVertex3i(-4, -4, -1);
  100.         glVertex3i( 4, -4, -1);
  101.         glVertex3i( 0,  3, -1);
  102.     glEnd();
  103.     }
  104.  
  105. }
  106.  
  107. static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
  108. {
  109.     if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
  110.     return GL_TRUE;
  111.     }
  112.     return GL_FALSE;
  113. }
  114.  
  115. int main(int argc, char *argv[])
  116. {
  117.     XVisualInfo *vi;
  118.     Display *dpy;
  119.     Colormap cmap;
  120.     Window window;
  121.     XSetWindowAttributes swa;
  122.     GLXContext cx;
  123.     XEvent event;
  124.     GLboolean needDisplay;
  125.     Pixmap pixmap;
  126.     GLXPixmap pm;
  127.     int gx, gy;
  128.     Window root;
  129.     unsigned int gwidth, gheight, gborder_width, gdepth;
  130.     Status xggStatus;
  131.     GC gc;
  132.     int rgb = 1, i;
  133.     rgb = 1;
  134.     for (i = 1; i < argc; i++) {
  135.     if (argv[i][0] == '-') {
  136.         switch (argv[i][1]) {
  137.         case 'c':
  138.         rgb = 0;
  139.         break;
  140.         }
  141.     }
  142.     }
  143.  
  144.     dpy = XOpenDisplay(0);
  145.     if (!dpy) {
  146.     fprintf(stderr, "Can't connect to display \"%s\"\n",
  147.         getenv("DISPLAY"));
  148.     return -1;
  149.     }
  150.  
  151.     vi = glXChooseVisual(dpy, DefaultScreen(dpy),
  152.         rgb ? RGBattributes : CIattributes);
  153.     if (!vi) {
  154.     fprintf(stderr, "No singlebuffered rgba visual on \"%s\"\n",
  155.         getenv("DISPLAY"));
  156.     return -1;
  157.     }
  158.  
  159.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
  160.         rgb ? AllocNone: AllocAll);
  161.     /* XXX
  162.     ** could use some colormap setting here.
  163.     */
  164.  
  165.     swa.border_pixel = 0;
  166.     swa.colormap = cmap;
  167.     swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
  168.         | KeyReleaseMask;
  169.     window = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 10, 10,
  170.         width, height,
  171.         0, vi->depth, InputOutput, vi->visual,
  172.         CWBorderPixel|CWColormap|CWEventMask, &swa);
  173.     XSetStandardProperties(dpy, window, "pixmap", "pixmap", None, argv,
  174.         argc, NULL);
  175.     XSetWMColormapWindows(dpy, window, &window, 1);
  176.     XMapWindow(dpy, window);
  177.     XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
  178.     gc = XCreateGC(dpy, window, 0, NULL);
  179.  
  180.     cx = glXCreateContext(dpy, vi, 0, GL_FALSE);
  181.     if (!glXMakeCurrent(dpy, window, cx)) {
  182.     fprintf(stderr, "Can't make window current to context\n");
  183.     return -1;
  184.     }
  185.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  186.  
  187.     /*******  Create Pixmap */
  188.     pixmap = XCreatePixmap(dpy, RootWindow(dpy, vi->screen),
  189.         width, height, vi->depth);
  190.     pm = glXCreateGLXPixmap(dpy, vi, pixmap);
  191.     xggStatus = XGetGeometry(dpy, pixmap, &root, &gx, &gy, &gwidth,
  192.         &gheight, &gborder_width, &gdepth);
  193.  
  194.     if (!glXMakeCurrent(dpy, pm, cx)) {
  195.     fprintf(stderr, "Can't make pixmap current to context\n");
  196.     return -1;
  197.     }
  198.     printf("rendering to pixmap\n");
  199.  
  200.     Init();
  201.  
  202.     printf("Hit p to render to a pixmap.\n");
  203.     printf("Hit w to render to a window.\n");
  204.     printf("Hit c to copy forward from the pixmap to the window.\n");
  205.  
  206.     needDisplay = GL_TRUE;
  207.     for (;;) {
  208.     do {
  209.         XNextEvent(dpy, &event);
  210.         switch (event.type) {
  211.         case Expose:
  212.         needDisplay = GL_TRUE;
  213.         break;
  214.         case ConfigureNotify:
  215.         width = event.xconfigure.width;
  216.         height = event.xconfigure.height;
  217.         Reshape(width, height);
  218.         needDisplay = GL_TRUE;
  219.         break;
  220.         case KeyPress:
  221.         {
  222.             char buf[100];
  223.             int rv;
  224.             KeySym ks;
  225.  
  226.             rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
  227.             switch (ks) {
  228.             case XK_c:
  229.             xggStatus = XGetGeometry(dpy, window, &root, &gx, &gy,
  230.                 &gwidth, &gheight, &gborder_width, &gdepth);
  231.             XCopyArea(dpy, pixmap, window, gc, 0, 0, gwidth,
  232.                 gheight, gx, gy);
  233.             printf("copying pixmap to window\n");
  234.             break;
  235.             case XK_p:
  236.             glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  237.             if (!glXMakeCurrent(dpy, pm, cx)) {
  238.                 fprintf(stderr,
  239.                     "Can't make pixmap current to context\n");
  240.                 return -1;
  241.             }
  242.             render_to_pixmap = GL_TRUE;
  243.             needDisplay = GL_TRUE;
  244.             printf("rendering to pixmap\n");
  245.             break;
  246.             case XK_w:
  247.             if (!glXMakeCurrent(dpy, window, cx)) {
  248.  
  249.                 fprintf(stderr,
  250.                     "Can't make window current to context\n");
  251.                 return -1;
  252.             }
  253.             render_to_pixmap = GL_FALSE;
  254.             needDisplay = GL_TRUE;
  255.             printf("rendering to window\n");
  256.             break;
  257.             case XK_Escape:
  258.             return 0;
  259.             }
  260.         }
  261.         break;
  262.         }
  263.     } while (XPending(dpy) != 0);
  264.  
  265.     if (needDisplay) {
  266.         needDisplay = GL_FALSE;
  267.         DoDisplay();
  268.         glFlush();
  269.     }
  270.     }
  271. }
  272.